/***
 * @Description: 用于网络收发包文件
 * @Author: Liverpool
 * @Date: 2023-12-10 22:41:52
 * @LastEditTime: 2023-12-11 22:53:35
 * @LastEditors: Liverpool
 */
#include "SendReceivePackets.h"

/***
 * @description: 向定义好的网卡地址发送数据包
 * @Author: Liverpool
 * @Date: 2023-12-11 01:10:25
 * @return {*}
 * @param {char} *ip 配置好的网卡IP地址
 * @param {uint8_t} *mac_addr 配置好的网卡mac地址
 */
void Test_Send_Packet(const char *ip, const uint8_t *mac_addr)
{
    pcap_t *pcap = pcap_device_open(ip, mac_addr); // 打开所定义的网卡 pcap_device_open()在后续进行介绍
    while (pcap)                                   // 定义的网卡不为空
    {
        static uint8_t buffer[1024];              // 定义要发送的数据包
        static int count = 0;                     // 发包的计数器
        plat_printf("begin test: %d\n", count++); // 进行发包计数打印 plat_printf()是打印函数 适配于多系统中 在windows下相当于printf()
        // 构建数据包
        for (int i = 0; i < sizeof(buffer); i++)
        {
            buffer[i] = i;
        }

        if (pcap_inject(pcap, buffer, sizeof(buffer)) == -1) // 向写入的网卡地址进行发送数据包 发送失败会返回-1
        {
            plat_printf("pcap send: send packet failed %s\n", pcap_geterr(pcap)); // 打印不发送成功的原因
            break;
        }
        sys_sleep(10); // 休息10ms
    }
}

/***
 * @description: 测试接受设定网卡的数据并进行发送返回
 * @Author: Liverpool
 * @Date: 2023-12-11 22:51:43
 * @return {*}
 * @param {char} *ip 设置网卡的IP地址
 * @param {uint8_t} *mac_addr 设置网卡的mac地址
 */
void Test_Receive_Packet(const char *ip, const uint8_t *mac_addr)
{
    static int counter = 0;                   // 发送计数器
    static uint8_t buffer[1024];              // 数据收发的缓冲区
    struct pcap_pkthdr *packet_header = NULL; // 接收到包的包头指针
    const uint8_t *packet_data = NULL;        // 接收到包的数据内容头指针

    pcap_t *pcap = pcap_device_open(ip, mac_addr); // 打开所定义的网卡
    while (pcap)
    {
        if (pcap_next_ex(pcap, &packet_header, &packet_data) != 1) // 从指定网卡上接收数据包 函数接收到数据包后返回1
        {
            continue;
        }
        plat_printf("begin test: %d\n", counter++);                                          // 进行发包计数打印 plat_printf()是打印函数 适配于多系统中 在windows下相当于printf()
        int len = packet_header->len > sizeof(buffer) ? sizeof(buffer) : packet_header->len; // 判断收到的数据包的内容长度
        plat_memcpy(buffer, packet_data, len);                                               // 把packet中的数据复制到buffer中
        // 对接收到的数据进行略微修改在反发送回去
        buffer[0] = 20;
        buffer[1] = 23;
        if (pcap_inject(pcap, buffer, sizeof(buffer)) == -1) // 向写入的网卡地址进行发送数据包 发送失败会返回-1
        {
            plat_printf("pcap send: send packet failed %s\n", pcap_geterr(pcap)); // 打印不发送成功的原因
            break;
        }
    }
}